package org.iblink.gui.swing.views.component;

import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.IOException;

import javax.swing.tree.DefaultMutableTreeNode;

import org.iblink.core.domain.model.Category;
import org.iblink.gui.swing.dnd.flavor.CategoryFlavor;

/**
 * <p>A <code>CategoryNode</code> is a tree node representing a {@link org.iblink.core.domain.model.Category}.</p>
 * 
 * @author tpares
 *
 */
public class CategoryNode extends DefaultMutableTreeNode implements Transferable {

  /**
   * Generated default UID
   */
  private static final long serialVersionUID = 2486121690123628000L;
  
  private Category category;
  
  /**
   * <p>Creates a new node with name <code>nodeName</code>.</p>
   * <p>This node will not be representing any "real" {@link org.iblink.core.domain.model.Category}.</p>
   * @param nodeName the name of the node
   */
  public CategoryNode(String nodeName) {
    super(nodeName);
  }

  /**
   * <p>Creates a new node representing the given {@link org.iblink.core.domain.model.Category}.</p>
   * @param category the {@link org.iblink.core.domain.model.Category}the node should represent
   */
  public CategoryNode(Category category) {
    super(category.getName());
    this.category = category;
  }
  
  /**
   * <p>Return the {@link org.iblink.core.domain.model.Category} this node represents.</p>
   * @return the {@link org.iblink.core.domain.model.Category} represented by this node 
   */
  public Category getCategory() {
    return category;
  }
  
  /**
   * <p>Sets the {@link org.iblink.core.domain.model.Category} this node represents.</p>
   * @param category the {@link org.iblink.core.domain.model.Category} represented by this node 
   */
  public void setCategory(Category category) {
    this.category = category;
    setUserObject(category.getName());
  }
  
  /**
   * <p>Indicates whether or not a node can be edited or not.</p>
   * <p>A node can be edited if it represents a category.</p>
   * @return <code>true</code> if and only if the node can be edited, <code>false</code> otherwise.
   */
  public boolean isEditable() {
    return isCategory();
  }
  
  /**
   * <p>Indicates whether or not a node represents a {@link org.iblink.core.domain.model.Category} or not.</p>
   * @return <code>true</code> if and only if the node represents a {@link org.iblink.core.domain.model.Category}, <code>false</code> otherwise.
   */
  public boolean isCategory() {
    return getCategory() != null;
  }
  
  /**
   * Gets the node displayed name.
   * @return the name of this node
   */
  public String getName() {
    return isCategory() ? getCategory().getName() : getUserObject().toString();
  }

  @Override
  public Object getTransferData(DataFlavor flavor)
      throws UnsupportedFlavorException, IOException {
    return this;
  }

  @Override
  public DataFlavor[] getTransferDataFlavors() {
    DataFlavor[] flavors = new DataFlavor[1];
    try {
      flavors[0] = new CategoryFlavor();
    } catch (ClassNotFoundException e) {
      return null;
    }
    return flavors;
  }

  @Override
  public boolean isDataFlavorSupported(DataFlavor flavor) {
    return flavor != null && flavor instanceof CategoryFlavor;
  }
}
